<?php

namespace app\controller;

use app\BaseController;

/*
创建（Create）、更新（Update）、读取（Retrieve）和删除（Delete）
 */
class RsaController extends BaseController
{
    public $privateKey = './rsa_private_key.pem'; //私钥地址
    public $publicKey = './rsa_public_key.pem'; //公钥地址

    public $pri_key = '-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDvluFNiF8IrIsddK0OXBAvVBJH11OKvy9er1tRGn9yEJoHCJY3
EU/xz2LasCK8AwgRIqGJbvDBgRa70c3QT9j+wPqNqqJCSoSEKifnDUk1RgUReJT6
iqWaJyfM+WM3aHnKl61RZL4NV5qKe4CHMtaH/JtBCC/JzpuFER1P1IhCtQIDAQAB
AoGAaFYQb68/k4twWbeB1YsKEVJPU7HV08pGWrmKztr3PTk1mnKG2BxV8DwcFJg3
yCCZ1rx6FFuXxOzudYR8WIctO4wdsEbFky/cEGsfc6JJjiktmZaQ7MvobGNwnoFJ
QvRxDd+5uD87JE19iBSgUpLVtXbv+pZxSpD70vitnMdSctECQQD66Z5HsuC8DUPu
OLQHNN4ra5Op179Xlq7LiEFW4GaVgonw24kiLX23c7CK7295Rgxct1fwQKyuU9br
n2uj8toDAkEA9HJ85BWlm2OfUm6VI3Q99rjlpCnhRyz70+sEtf7if1SpctVxNTkX
UOnXlpPTohjAHNhzh9fa1hh/ySH9sRMu5wJAa//8uh3br/YBxFsx2lw+OPBQGe4c
lSXtzPu0LCHg5f/PQhYs28I696jbV6IiGFA3Z/0e4/HiohLCUp9HJMWWYwJACE53
pfyCUyRwfomZccn6bQ7dZtWxfQyvRgU/dLvDkJYc5/UO0sMs4qf/lnNRhrmWlaRZ
UK1qF0pf1ULdbw360wJBAObrYopW2kvIlE09j9SEgNtgVsmfZlf85c4EAZrFJP/T
8nMNKQGo92Gd3HvbjJ+ZBOP1IFt+FDAsXeSLWLAwJrg=
-----END RSA PRIVATE KEY-----';
    public $pub_key = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvluFNiF8IrIsddK0OXBAvVBJH
11OKvy9er1tRGn9yEJoHCJY3EU/xz2LasCK8AwgRIqGJbvDBgRa70c3QT9j+wPqN
qqJCSoSEKifnDUk1RgUReJT6iqWaJyfM+WM3aHnKl61RZL4NV5qKe4CHMtaH/JtB
CC/JzpuFER1P1IhCtQIDAQAB
-----END PUBLIC KEY-----';

    /**
     * RSA constructor.
     * @param null $publicKeyPath
     * @param null $privateKeyPath
     * @param null $publicKey
     * @param null $privateKey
     * @throws FileNotFoundException
     */
    public function __construct($publicKeyPath = null, $privateKeyPath = null, $publicKey = null, $privateKey = null)
    {

        if ($this->checkKeyFile($publicKeyPath)) {
            $this->pub_key = openssl_pkey_get_public(file_get_contents($publicKeyPath));
        }

        if ($this->checkKeyFile($privateKeyPath)) {
            $this->pri_key = openssl_pkey_get_private(file_get_contents($privateKeyPath));
        }

        if (!is_null($publicKey)) {
            $this->pub_key = openssl_pkey_get_public($this->formatterPublicKey($publicKey));
        }

        if (!is_null($privateKey)) {
            $this->pri_key = openssl_pkey_get_private($this->formatterPrivateKey($privateKey));
        }

    }

    /**
     * 校验文件是否存在
     * @param $keyPath string 文件路径
     * @return bool
     * @throws FileNotFoundException
     */
    public function checkKeyFile($keyPath)
    {
        if (!is_null($keyPath)) {
            if (!file_exists($keyPath)) {
                throw new FileNotFoundException($keyPath);
            }

            return true;
        }

        return false;
    }

    /**
     * 格式化公钥
     * @param $publicKey string 公钥
     * @return string
     */
    public function formatterPublicKey($publicKey)
    {
        if (str_contains('-----BEGIN PUBLIC KEY-----', $publicKey)) {
            return $publicKey;
        }

        $str = chunk_split($publicKey, 64, PHP_EOL); //在每一个64字符后加一个\n
        $publicKey = "-----BEGIN PUBLIC KEY-----" . PHP_EOL . $str . "-----END PUBLIC KEY-----";

        return $publicKey;
    }

    /**
     * 格式化私钥
     * @param $privateKey string 公钥
     * @return string
     */
    public function formatterPrivateKey($privateKey)
    {
        if (str_contains('-----BEGIN RSA PRIVATE KEY-----', $privateKey)) {
            return $privateKey;
        }

        $str = chunk_split($privateKey, 64, PHP_EOL); //在每一个64字符后加一个\n
        $privateKey = "-----BEGIN RSA PRIVATE KEY-----" . PHP_EOL . $str . "-----END RSA PRIVATE KEY-----";

        return $privateKey;
    }

    /**
     *  公钥加密（分段加密）
     *  emptyStr    需要加密字符串
     */
    public function encrypt($str)
    {
        $crypted = array();
        $data = $str;
        $dataArray = str_split($data, 117);
        foreach ($dataArray as $subData) {
            $subCrypted = null;
            openssl_public_encrypt($subData, $subCrypted, $this->pub_key);
            $crypted[] = $subCrypted;
        }
        $crypted = implode('', $crypted);
        return base64_encode($crypted);
    }

    /**
     *  私钥解密（分段解密）
     *  @encrypstr  加密字符串
     */
    public function decrypt($encryptstr)
    {
        $encryptstr = base64_decode($encryptstr);
        $decrypted = array();
        $dataArray = str_split($encryptstr, 128);

        foreach ($dataArray as $subData) {
            $subDecrypted = null;
            openssl_private_decrypt($subData, $subDecrypted, $this->pri_key);
            $decrypted[] = $subDecrypted;
        }
        $decrypted = implode('', $decrypted);
        return $decrypted;
    }
    public function rsa()
    {
        $result = new self();
 
        $data = '{"deviceSn":"123456","deviceId":"123456"}';
         
        $dataEn = $result->encrypt($data);
        $re['dataEn'] = $dataEn;
        $dataDe = $result->decrypt($dataEn);
        $re['dataDe'] = $dataDe;
        return success($re);
    }

}
